#ifndef _WX_GTK_TEXTCTRL_H_
#define _WX_GTK_TEXTCTRL_H_

typedef struct _GtkTextMark GtkTextMark;

class wxTextCtrl: public wxTextCtrlBase {
  public:
    wxTextCtrl() { Init(); }
    wxTextCtrl( wxWindow *parent,
                wxWindowID id,
                const wxString &value = wxEmptyString,
                const wxPoint &pos = wxDefaultPosition,
                const wxSize &size = wxDefaultSize,
                long style = 0,
                const wxValidator& validator = wxDefaultValidator,
                const wxString &name = wxTextCtrlNameStr );

    virtual ~wxTextCtrl();

    bool Create( wxWindow *parent,
                 wxWindowID id,
                 const wxString &value = wxEmptyString,
                 const wxPoint &pos = wxDefaultPosition,
                 const wxSize &size = wxDefaultSize,
                 long style = 0,
                 const wxValidator& validator = wxDefaultValidator,
                 const wxString &name = wxTextCtrlNameStr );

    virtual wxString GetValue() const;
    virtual bool IsEmpty() const;

    virtual int GetLineLength( long lineNo ) const;
    virtual wxString GetLineText( long lineNo ) const;
    virtual int GetNumberOfLines() const;

    virtual bool IsModified() const;
    virtual bool IsEditable() const;
    virtual void GetSelection( long* from, long* to ) const;

    // operations
    // ----------

    // editing
    virtual void Clear();
    virtual void Replace( long from, long to, const wxString& value );
    virtual void Remove( long from, long to );

    // sets/clears the dirty flag
    virtual void MarkDirty();
    virtual void DiscardEdits();

    virtual void SetMaxLength( unsigned long len );

    // writing text inserts it at the current position, appending always
    // inserts it at the end
    virtual void WriteText( const wxString& text );
    virtual void AppendText( const wxString& text );

    // apply text attribute to the range of text (only works with richedit
    // controls)
    virtual bool SetStyle( long start, long end, const wxTextAttr& style );
    virtual long XYToPosition( long x, long y ) const;
    virtual bool PositionToXY( long pos, long *x, long *y ) const;

    virtual void ShowPosition( long pos );

    virtual wxTextCtrlHitTestResult HitTest( const wxPoint& pt, long *pos ) const;
    virtual wxTextCtrlHitTestResult HitTest( const wxPoint& pt,
        wxTextCoord *col,
        wxTextCoord *row ) const {
      return wxTextCtrlBase::HitTest( pt, col, row );
    }

    // Clipboard operations
    virtual void Copy();
    virtual void Cut();
    virtual void Paste();

    // Undo/redo
    virtual void Undo();
    virtual void Redo();

    virtual bool CanUndo() const;
    virtual bool CanRedo() const;

    // Insertion point
    virtual void SetInsertionPoint( long pos );
    virtual void SetInsertionPointEnd();
    virtual long GetInsertionPoint() const;
    virtual wxTextPos GetLastPosition() const;

    virtual void SetSelection( long from, long to );
    virtual void SetEditable( bool editable );

    // Overridden wxWindow methods
    virtual void SetWindowStyleFlag( long style );
    virtual bool Enable( bool enable = true );
    void OnDropFiles( wxDropFilesEvent &event );
    void OnChar( wxKeyEvent &event );
    void OnCut( wxCommandEvent& event );
    void OnCopy( wxCommandEvent& event );
    void OnPaste( wxCommandEvent& event );
    void OnUndo( wxCommandEvent& event );
    void OnRedo( wxCommandEvent& event );
    void OnUpdateCut( wxUpdateUIEvent& event );
    void OnUpdateCopy( wxUpdateUIEvent& event );
    void OnUpdatePaste( wxUpdateUIEvent& event );
    void OnUpdateUndo( wxUpdateUIEvent& event );
    void OnUpdateRedo( wxUpdateUIEvent& event );
    bool SetFont( const wxFont& font );
    bool SetForegroundColour( const wxColour& colour );
    bool SetBackgroundColour( const wxColour& colour );
    GtkWidget* GetConnectWidget();
    void SetUpdateFont( bool ( update ) ) { }
    virtual void Freeze();
    virtual void Thaw();
    virtual void OnParentEnable( bool enable ) ;
    void IgnoreNextTextUpdate( int n = 1 ) { m_countUpdatesToIgnore = n; }
    bool IgnoreTextUpdate();
    void DontMarkDirtyOnNextChange() { m_dontMarkDirty = true; }
    bool MarkDirtyOnChange();
    virtual bool GTKProcessEvent( wxEvent& event ) const;
    static wxVisualAttributes
    GetClassDefaultAttributes( wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL );

    // has the control been frozen by Freeze()?
    bool IsFrozen() const { return m_freezeCount > 0; }

  protected:
    virtual wxSize DoGetBestSize() const;
    virtual void DoApplyWidgetStyle( GtkRcStyle *style );
    virtual GdkWindow *GTKGetWindow( wxArrayGdkWindows& windows ) const;
    void Init();
    virtual bool UseGTKStyleBase() const { return true; }
    virtual void DoSetValue( const wxString &value, int flags = 0 );
    void GTKSetEditable();
    void GTKSetVisibility();
    void GTKSetWrapMode();
    void GTKSetJustification();
  private:
    void ChangeFontGlobally();
    wxFontEncoding GetTextEncoding() const;


    GtkWidget  *m_text;

    bool        m_modified: 1;
    bool        m_dontMarkDirty: 1;

    int         m_countUpdatesToIgnore;
    GtkTextBuffer *m_buffer;

    // number of calls to Freeze() minus number of calls to Thaw()
    unsigned m_freezeCount;
    GtkTextMark* m_showPositionOnThaw;
    void OnUrlMouseEvent( wxMouseEvent& );
    GdkCursor *m_gdkHandCursor;
    GdkCursor *m_gdkXTermCursor;

    DECLARE_EVENT_TABLE()
    DECLARE_DYNAMIC_CLASS( wxTextCtrl )
};

#endif // _WX_GTK_TEXTCTRL_H_
